package com.dhh.sky.activity;

import java.util.HashMap;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.dhh.sky.R;
import com.dhh.sky.model.SkyDriveObject;
import com.dhh.sky.service.MusicPlayerService;
import com.dhh.sky.util.CUtil;
import com.dhh.sky.util.Constant;
import com.dhh.sky.util.FileManager;
import com.dhh.sky.util.MusicUtilities;
import com.dhh.sky.util.SongsManager;

public class AudioPlayerActivity extends SherlockFragmentActivity{
	private MusicPlayerService playerService;
	private ImageButton btnPlaylist;
	private TextView songTitleLabel;
	private ImageButton btnPlay;
	private SeekBar songProgressBar;
	private TextView songCurrentDurationLabel;
	private TextView songTotalDurationLabel;
	private ImageView coverImage;
	private ImageButton btnRepeat;
	private ImageButton btnShuffle;
	private ImageButton btnForward;
	private ImageButton btnBackward;
	private ImageButton btnNext;
	private ImageButton btnPrevious;
	private int seekForwardTime = 5000; // 5000 milliseconds
	private int seekBackwardTime = 5000; // 5000 milliseconds
	private String songPath;
	private MusicUtilities utils;
	private Handler mHandler = new Handler();
	private List<HashMap<String, String>> songList;
	private SongsManager songManager;
	private FileManager fm;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.player);
		
		getSupportActionBar().hide();

		utils = new MusicUtilities();
		initView();
		songManager = new SongsManager();
		songList = songManager.getPlayList();
		fm = new FileManager(this);
		Bundle bundle = this.getIntent().getExtras();
		if(bundle!=null){
			songPath = bundle.getString(Constant.PARAM_PATH);
		}
	}
	
	@Override
    protected void onResume(){
        super.onResume();
        if(!isAudioServiceRunning())
        	startService(new Intent(this, MusicPlayerService.class));
        bindService(new Intent(this, MusicPlayerService.class), audioPlaybackServiceConnection, Context.BIND_ABOVE_CLIENT);
    }

	@Override
	protected void onPause() {
		super.onPause();
		unbindService(audioPlaybackServiceConnection);
		mHandler.removeCallbacks(mUpdateTimeTask);
	}
	
	private ServiceConnection audioPlaybackServiceConnection = new ServiceConnection(){
		@Override
		public void onServiceConnected(ComponentName componentName,IBinder iBinder) {
			playerService = ((MusicPlayerService.AudioPlaybackServiceBinder) iBinder).getService();
			if(!playerService.isPlaying()){
				playSong();
			}else{				
				if(songPath!=null && !songPath.toLowerCase().contains(playerService.getCurrentSongPath().toLowerCase())){
					playSong();
				}
			}
			
			updateUI();
			updateProgressBar();
		}

		@Override
		public void onServiceDisconnected(ComponentName componentName){
			playerService = null;
			updateUI();
		}
	};
	
	private void playSong(){
		int index = 0;
		if((songPath)!=null){
			index = songManager.getSongIndex(songPath);
		}
		
		playSong(index);
	}
	
	private void playSong(int index){
		playerService.playSong(index);
		songProgressBar.setMax(100);
		songProgressBar.setProgress(0);
		
		updateUI();
	}
	
	private void updateUI(){
		MediaMetadataRetriever mmr = new MediaMetadataRetriever();
		mmr.setDataSource(playerService.getCurrentSongPath());
		String songName = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);	
		if(songName!=null){
			songTitleLabel.setText(songName);
		}else{
			SkyDriveObject obj = fm.getFile(CUtil.getFilePreName(playerService.getCurrentSongTitle()));
			if(obj!=null){
				songTitleLabel.setText(CUtil.getFilePreName(obj.getName()));
			}else{
				songTitleLabel.setText(CUtil.getFilePreName(playerService.getCurrentSongTitle()));
			}
		}
		
		if(playerService.isPlaying()){
			btnPlay.setImageResource(R.drawable.btn_pause);
		}else{
			btnPlay.setImageResource(R.drawable.btn_play);
		}
		initCoverImage();
		
		if(playerService.isRepeat()){
			this.btnRepeat.setImageResource(R.drawable.btn_repeat_focused);
		}
		
		if(playerService.isShuffle()){
			this.btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
		}
	}
	
	private void initCoverImage(){
		MediaMetadataRetriever mmr = new MediaMetadataRetriever();
		mmr.setDataSource(playerService.getCurrentSongPath());
		byte[] picBytes = mmr.getEmbeddedPicture();
		if(picBytes!=null && picBytes.length>0){
			Bitmap bitMap = BitmapFactory.decodeByteArray(mmr.getEmbeddedPicture(), 0, picBytes.length);
			coverImage.setImageBitmap(bitMap);
		}
	}
	
	private void initView(){
		songTitleLabel = (TextView) findViewById(R.id.songTitle);
		songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
		btnPlay = (ImageButton) findViewById(R.id.btnPlay);
		songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
		songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);		
		coverImage = (ImageView) findViewById(R.id.player_cover);
		btnRepeat = (ImageButton) findViewById(R.id.btnRepeat);
		btnShuffle = (ImageButton) findViewById(R.id.btnShuffle);
		btnForward = (ImageButton) findViewById(R.id.btnForward);
		btnBackward = (ImageButton) findViewById(R.id.btnBackward);
		btnNext = (ImageButton) findViewById(R.id.btnNext);
		btnPrevious = (ImageButton) findViewById(R.id.btnPrevious);
		btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
		
		btnPlaylist.setOnClickListener(new View.OnClickListener() {			
			@Override
			public void onClick(View arg0) {
				startActivity(new Intent(AudioPlayerActivity.this,SongListActivity.class));
			}
		});
		
		btnPlay.setOnClickListener(new View.OnClickListener() {			
			@Override
			public void onClick(View arg0) {
				if(playerService!=null){
					if(playerService.isPlaying()){
						playerService.pausePlay();
					}else{
						playerService.startPlay();
					}
					
					updateUI();					
				}else{
					//TODO how deal with while service is stopped
				}
			}
		});
		
		songProgressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {			
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				mHandler.removeCallbacks(mUpdateTimeTask);
				int totalDuration = playerService.getDuration();
				int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
				
				playerService.seekTo(currentPosition);
				
				updateProgressBar();
			}
			
			@Override
			public void onStartTrackingTouch(SeekBar seekBar){
				mHandler.removeCallbacks(mUpdateTimeTask);
			}
			
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {				
			}
		});
		
		btnRepeat.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				if(playerService.isRepeat()){
					playerService.setRepeat(false);
					Toast.makeText(getApplicationContext(), "Repeat is OFF", Toast.LENGTH_SHORT).show();
					btnRepeat.setImageResource(R.drawable.btn_repeat);
				}else{
					// make repeat to true
					playerService.setRepeat(true);
					Toast.makeText(getApplicationContext(), "Repeat is ON", Toast.LENGTH_SHORT).show();
					// make shuffle to false
					playerService.setShuffle(false);
					btnRepeat.setImageResource(R.drawable.btn_repeat_focused);
					btnShuffle.setImageResource(R.drawable.btn_shuffle);
				}	
			}
		});
		
		btnShuffle.setOnClickListener(new View.OnClickListener() {			
			@Override
			public void onClick(View arg0) {
				if(playerService.isShuffle()){
					playerService.setShuffle(false);
					Toast.makeText(getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show();
					btnShuffle.setImageResource(R.drawable.btn_shuffle);
				}else{
					// make repeat to true
					playerService.setShuffle(true);
					Toast.makeText(getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show();
					// make shuffle to false
					playerService.setRepeat(false);
					btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
					btnRepeat.setImageResource(R.drawable.btn_repeat);
				}	
			}
		});
		
		btnForward.setOnClickListener(new View.OnClickListener() {			
			@Override
			public void onClick(View arg0) {
				// get current song position				
				int currentPosition = playerService.getCurrentPosition();
				// check if seekForward time is lesser than song duration
				if(currentPosition + seekForwardTime <= playerService.getDuration()){
					// forward song
					playerService.seekTo(currentPosition + seekForwardTime);
				}else{
					// forward to end position
					playerService.seekTo(playerService.getDuration());
				}
			}
		});
		
		btnBackward.setOnClickListener(new View.OnClickListener() {			
			@Override
			public void onClick(View arg0) {
				// get current song position				
				int currentPosition = playerService.getCurrentPosition();
				// check if seekBackward time is greater than 0 sec
				if(currentPosition - seekBackwardTime >= 0 ){
					// forward song
					playerService.seekTo(currentPosition - seekBackwardTime);
				}else{
					// backward to starting position
					playerService.seekTo(0);
				}
				
			}
		});
		
		/**
		 * Next button click event
		 * Plays next song by taking currentSongIndex + 1
		 * */
		btnNext.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// check if next song is there or not
				if(playerService.getCurrentSongIndex() < (songList.size() - 1)){
					playSong(playerService.getCurrentSongIndex() + 1);
				}else{
					// play first song
					playSong(0);
				}
				
			}
		});
		
		/**
		 * Back button click event
		 * Plays previous song by currentSongIndex - 1
		 * */
		btnPrevious.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				if(playerService.getCurrentSongIndex() > 0){
					playSong(playerService.getCurrentSongIndex() - 1);
				}else{
					// play last song
					playSong(songList.size() - 1);
				}
				
			}
		});
	}
	
	private boolean isAudioServiceRunning() {
	    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
	    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
	        if (MusicPlayerService.class.getName().equals(service.service.getClassName())) {
	            return true;
	        }
	    }
	    return false;
	}
	
	public void updateProgressBar() {
		   songProgressBar.setMax(100);
        mHandler.postDelayed(mUpdateTimeTask, 100);        
    }
	
	private Runnable mUpdateTimeTask = new Runnable() {
		   public void run() {
			   try{
				   long totalDuration = playerService.getDuration();
				   long currentDuration = playerService.getCurrentPosition();
				  
				   // Displaying Total Duration time
				   songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
				   // Displaying time completed playing
				   songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));
				   
				   // Updating progress bar
				   int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
				   //Log.d("Progress", ""+progress);
				   songProgressBar.setProgress(progress);
				   
				   // Running this thread after 100 milliseconds
			       mHandler.postDelayed(this, 100);
			   }catch(Exception e){
				   Log.e(Constant.TAG, e.getMessage(),e);
			   }
		   }
		};
	
}
